﻿using System;
using System.Collections.Generic;
using System.Linq;
using DLM.Domain.Model;
using DLM.Domain.Repositories;
using DLM.Infrastructure.Domain;
using DLM.Infrastructure.UnitOfWork;
using DLM.Infrastructure.Authentication;
using DLM.Services.Interfaces;
using DLM.Infrastructure.Security;

namespace DLM.Services.Implementations
{
    public class AdminService : IAdminService
    {

        private IAdminUserRepository adminRepository;
        private IAccountRepositroy accountRepository;
        private IFriendRepository friendRepository;
        private IFormsAuthentication formAuth;
        private IUnitOfWork unitOfWork;
        private INoticeRepository noticeRepository;
        private ILogRepository logRepository;

        public AdminService(IAdminUserRepository adminRepository,
            IFormsAuthentication formAuth,
            INoticeRepository noticeRepository,
            ILogRepository logRepository)
        {
            this.adminRepository = adminRepository;
            this.formAuth = formAuth;
            this.noticeRepository = noticeRepository;
            this.logRepository = logRepository;
        }

        public void Login(AdminUser admin)
        {
            if (admin == null)
            {
                throw new ArgumentNullException("Admin cannot be null!");
            }
            var currentAdmin = this.adminRepository.FindByName(admin.Administrator);
            if (currentAdmin == null)
            {
                throw new System.Security.Authentication.InvalidCredentialException("Administrator is not exist!");
            }
            if (Md5Encrypt.HashPassword(admin.Password) == currentAdmin.Password)
            {
                this.formAuth.SetAuthenticationToken(admin.Administrator,"Admin");
            }

        }

        public void LogOut()
        {
            this.formAuth.SignOut();
        }


        public void AddNotice(string subject, string content)
        {
            if (string.IsNullOrEmpty(subject))
            {
                throw new ArgumentNullException("Subject");
            }

            if (string.IsNullOrEmpty(content))
            {
                throw new ArgumentNullException("Content");
            }

            Notice notice = new Notice 
            {
                 Subject = subject,
                 Content = content,
                 CreateDate = DateTime.Now
            };
            this.noticeRepository.Add(notice);
           
        }

        public void UpdateNotice(Notice notice)
        {
            if (notice == null)
            {
                throw new ArgumentNullException("Notice");
            }
            this.noticeRepository.Save(notice);
        }

        public void RemoveNotice(int nid)
        {
            if (nid < 0)
            {
                throw new ArgumentOutOfRangeException("nid");
            }
            var notice = this.noticeRepository.FindBy(nid);
            this.noticeRepository.Remove(notice);
        }


        public IEnumerable<Notice> Notices()
        {
            return this.noticeRepository.FindAll();
        }


        public AdminUser GetAdmin(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("Account");
            }
            return this.adminRepository.FindByName(name);
        }

        public void ChangePassword(string accountName,string orginPass, string newPass)
        {
            if (string.IsNullOrEmpty(orginPass))
            {
                throw new ArgumentNullException("OrginPassword");
            }
            if (string.IsNullOrEmpty(newPass))
            {
                throw new ArgumentNullException("NewPassword");
            }
            if (orginPass == newPass)
            {
                var account = this.adminRepository.FindByName(accountName);
                if (account != null)
                {
                    account.Password = Md5Encrypt.HashPassword(newPass);
                    this.adminRepository.Save(account);
                }
            }
        }


        public IEnumerable<Log> GetLog(int pageIndex, int pageSize)
        {
            return this.logRepository.FindAll(pageIndex, pageSize);
        }
    }
}
